/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package TimeRecording.business;

import TimeRecording.tables.ClockedPeriod;
import TimeRecording.tables.Employee;
import TimeRecording.tables.WeeklyTime;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import javax.persistence.EntityManager;

/**
 *
 * @author david
 */
public class ClockedTime {

    public static void reassessClockedTime(EntityManager entityManager,
            Employee employee, DateRange dateRange) {

        // Build a map of hours worked on the days of the period

        List<ClockedPeriod> periods = ClockedPeriod.
                getClockedPeriodsForEmployeeAndPeriod(
                        entityManager, employee, dateRange);

        HashMap<Date, Double> clockedHoursMap = new HashMap<Date, Double>();
        for (ClockedPeriod period : periods) {

            Date dateClocked = period.getClockedPeriodPK().getClockedIn();
            double hoursForPeriod = period.getDuration();

            Double hoursForDay = clockedHoursMap.get(dateClocked);
            if (hoursForDay == null) {
                clockedHoursMap.put(dateClocked, hoursForPeriod);
            } else {
                clockedHoursMap.put(dateClocked, hoursForDay + hoursForPeriod);
            }
        }

        // Get a list of existing timesheets

        List<WeeklyTime> timesheets = WeeklyTime.
                getWeeklyTimeByEmployeeAndDateRange(
                        entityManager, employee, dateRange);

        GregorianCalendar clockedDate = new GregorianCalendar();
        clockedDate.setTime(dateRange.getFromDate());

        GregorianCalendar endDate = new GregorianCalendar();
        endDate.setTime(dateRange.getToDate());

        while (!clockedDate.after(endDate)) {

            // Find the correct timesheet entry
            GregorianCalendar startOfWeek =
                    DaisyChainUtilities.firstDayOfWeek(clockedDate);

            WeeklyTime selectedTimesheet = null;
            for (WeeklyTime timesheet : timesheets) {
                if (timesheet.getWeeklyTimePK().
                        getWeekCommencing().equals(startOfWeek.getTime())) {
                    selectedTimesheet = timesheet;
                    break;
                }
            }

            // We have no such timesheet so let's create one
            if (selectedTimesheet == null) {
                selectedTimesheet = new WeeklyTime(
                        employee.getEmployeeId(), startOfWeek.getTime());
                entityManager.persist(selectedTimesheet);

                // Don't forget to add it to our collection
                timesheets.add(selectedTimesheet);
            }

            // Get details of the old and new clocked totals
            Double clocked = clockedHoursMap.get(clockedDate.getTime());
            if (clocked == null) {
                clocked = 0.0;
            }
            double oldClocked = selectedTimesheet.getClocked(clockedDate);

            if (clocked != oldClocked) {
                selectedTimesheet.setClocked(clockedDate, clocked);
            }

            clockedDate.add(GregorianCalendar.DATE, 1);
        }
    }

    public static void reassessClockedTime(
            EntityManager entityManager, DateRange dateRange) {

        List<Employee> employees = Employee.getActiveEmployees(entityManager);
        
        for (Employee employee : employees) {
            reassessClockedTime(entityManager, employee, dateRange);
        }
    }
}
